package com.fmboy.MXH.nav.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fmboy.MXH.nav.domain.dto.NavigationQueryDTO;
import com.fmboy.MXH.nav.domain.entities.Navigation;
import com.fmboy.MXH.nav.domain.pojo.NavigationVO;
import com.fmboy.MXH.nav.mapper.NavigationMapper;
import com.fmboy.MXH.nav.service.NavigationService;
import com.fmboy.MXH.nav.utils.UserContext;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class NavigationServiceImpl extends ServiceImpl<NavigationMapper, Navigation> implements NavigationService {

    @Resource
    private NavigationMapper navigationMapper;

    @Override
    public List<NavigationVO> getNavigation(NavigationQueryDTO navigationQueryDTO) {
        Long userId = UserContext.getUserId();
        QueryWrapper<Navigation> queryWrapper = new QueryWrapper<Navigation>().eq("user_id", userId);
        buildQueryWrapper(queryWrapper, navigationQueryDTO);

        List<Navigation> navigations = navigationMapper.selectList(queryWrapper);
        return saveNavigation(navigations);
    }

    @Override
    public NavigationVO getNavigationById(Integer id) {
        validateId(id);
        Navigation navigation = this.getById(id);
        if (navigation == null) {
            throw new RuntimeException("导航不存在");
        }

        List<NavigationVO> navigationVOS = saveNavigation(Collections.singletonList(navigation));
        return navigationVOS.get(0);

    }

    @Override
    public void saveNavigation(NavigationQueryDTO navigationQueryDTO) {
        validateNavigationQueryDTO(navigationQueryDTO);
        Navigation navigation = createNavigationFromDTO(navigationQueryDTO);
        this.save(navigation);
    }

    @Override
    public void updateNavigationById(NavigationQueryDTO navigationQueryDTO) {
        validateNavigationQueryDTO(navigationQueryDTO); // 验证导航信息

        Navigation originalNavigation = navigationMapper.selectById(navigationQueryDTO.getId());
        if (originalNavigation == null) {
            throw new RuntimeException("导航不存在");
        }

        LambdaUpdateWrapper<Navigation> updateWrapper = buildUpdateWrapper(navigationQueryDTO, originalNavigation);
        boolean updated = navigationMapper.update(null, updateWrapper) > 0;
        if (!updated) {
            throw new RuntimeException("导航信息更新失败");
        }
    }


    private void buildQueryWrapper(QueryWrapper<Navigation> queryWrapper, NavigationQueryDTO navigationQueryDTO) {
        if (StringUtils.isNotBlank(navigationQueryDTO.getNavigation_name())) {
            // 模糊查询导航名称
            queryWrapper.like("navigation_name", navigationQueryDTO.getNavigation_name());
        }
        if (navigationQueryDTO.getCategory_id() != null) {
            // 精确匹配类别ID
            queryWrapper.eq("category_id", navigationQueryDTO.getCategory_id());
        }
        if (StringUtils.isNotBlank(navigationQueryDTO.getState())) {
            // 精确匹配状态
            queryWrapper.eq("state", navigationQueryDTO.getState());
        }
    }

    private void validateId(Integer id) {
        if (id == null) {
            throw new RuntimeException("ID不能为空");
        }
    }

    private void validateNavigationQueryDTO(NavigationQueryDTO navigationQueryDTO) {
        if (navigationQueryDTO == null) {
            throw new RuntimeException("导航信息不能为空");
        }
        if (StringUtils.isBlank(navigationQueryDTO.getNavigation_name())) {
            throw new RuntimeException("导航名称不能为空");
        }
        if (StringUtils.isBlank(navigationQueryDTO.getNavigation_logo())) {
            throw new RuntimeException("导航图标不能为空");
        }
        if (StringUtils.isBlank(navigationQueryDTO.getNavigation_url())) {
            throw new RuntimeException("导航链接不能为空");
        }
        if (navigationQueryDTO.getCategory_id() == null) {
            throw new RuntimeException("导航分类不能为空");
        }
    }

    private Navigation createNavigationFromDTO(NavigationQueryDTO navigationQueryDTO) {
        Navigation navigation = new Navigation();
        navigation.setUserId(Math.toIntExact(UserContext.getUserId()));
        navigation.setCategoryId(navigationQueryDTO.getCategory_id());
        navigation.setNavigationName(navigationQueryDTO.getNavigation_name());
        navigation.setNavigationLogo(navigationQueryDTO.getNavigation_logo());
        navigation.setNavigationUrl(navigationQueryDTO.getNavigation_url());
        navigation.setNavigationText(navigationQueryDTO.getNavigation_text());
        navigation.setSortOrder((int) (count() + 1));
        navigation.setCreateTime(LocalDateTime.now());
        navigation.setUpdateTime(LocalDateTime.now());
        return navigation;
    }

    private LambdaUpdateWrapper<Navigation> buildUpdateWrapper(NavigationQueryDTO navigationQueryDTO, Navigation originalNavigation) {
        LambdaUpdateWrapper<Navigation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Navigation::getId, navigationQueryDTO.getId())
                .set(Navigation::getUserId, UserContext.getUserId())
                .set(Navigation::getCategoryId, navigationQueryDTO.getCategory_id())
                .set(Navigation::getNavigationName, navigationQueryDTO.getNavigation_name())
                .set(Navigation::getNavigationLogo, navigationQueryDTO.getNavigation_logo())
                .set(Navigation::getNavigationUrl, navigationQueryDTO.getNavigation_url())
                .set(Navigation::getNavigationText, navigationQueryDTO.getNavigation_text())
                .set(Navigation::getSortOrder, originalNavigation.getSortOrder())
                .set(Navigation::getUpdateTime, new Date());
        return updateWrapper;
    }

    public List<NavigationVO> saveNavigation(List<Navigation> navigationList) {
        List<NavigationVO> navigationVoList = new ArrayList<>();
        for (Navigation navigation : navigationList) {
            NavigationVO navigationVO = new NavigationVO();
            navigationVO.setId(navigation.getId());
            navigationVO.setCategory_id(navigation.getCategoryId());
            navigationVO.setNavigation_name(navigation.getNavigationName());
            navigationVO.setNavigation_logo(navigation.getNavigationLogo());
            navigationVO.setNavigation_url(navigation.getNavigationUrl());
            navigationVO.setNavigation_text(navigation.getNavigationText());
            navigationVO.setState(navigation.getState());
            navigationVO.setReason(navigation.getReason());
            navigationVO.setCreate_time(navigation.getCreateTime());
            navigationVO.setUpdate_time(navigation.getUpdateTime());
            navigationVoList.add(navigationVO);
        }
        return navigationVoList;
    }

    @Override
    public void updateNavigationState(NavigationQueryDTO navigationQueryDTO) {
        // 空值检查
        Objects.requireNonNull(navigationQueryDTO, "CategoryDTO 不能为空");
        Objects.requireNonNull(navigationQueryDTO.getId(), "ID 不能为空");
        Objects.requireNonNull(navigationQueryDTO.getReason(), "Reason 不能为空");


        // 查询当前分类的状态
        QueryWrapper<Navigation> queryWrapper = new QueryWrapper<Navigation>().eq("id", navigationQueryDTO.getId());
        Navigation navigation = navigationMapper.selectOne(queryWrapper);

        if (navigation == null) {
            throw new RuntimeException("导航不存在");
        }

        String currentState = navigation.getState();
        String newState = determineNewState(currentState);

        if (newState == null) {
            throw new RuntimeException("未知的导航状态");
        }

        // 更新分类状态
        navigation.setState(newState);
        navigation.setUpdateTime(LocalDateTime.now());
        navigation.setReason(navigationQueryDTO.getReason());
        this.updateById(navigation);
    }

    @Override
    public void deleteById(Integer id) {
        if (id == null) {
            throw new RuntimeException("ID不能为空");
        }
        Navigation navigation = this.getById(id);
        if (navigation.getState().equals("已发布")) {
            throw new RuntimeException("删除失败，此导航已发布，请先取消发布！");
        }
        if (navigation.getState().equals("待审核")) {
            throw new RuntimeException("删除失败，此导航待审核中，请等待审核！");
        }
        this.removeById(id);
    }

    @Override
    public List<NavigationVO> AdminGetNavigation(NavigationQueryDTO navigationQueryDTO) {

        QueryWrapper<Navigation> queryWrapper = new QueryWrapper<>();
        buildQueryWrapper(queryWrapper, navigationQueryDTO);

        List<Navigation> navigations = navigationMapper.selectList(queryWrapper);
        return saveNavigation(navigations);
    }

    @Override
    public void AdminUpdateNavigationById(NavigationQueryDTO navigationQueryDTO) {
        validateNavigationQueryDTO(navigationQueryDTO); // 验证导航信息

        Navigation originalNavigation = navigationMapper.selectById(navigationQueryDTO.getId());
        if (originalNavigation == null) {
            throw new RuntimeException("导航不存在");
        }

        LambdaUpdateWrapper<Navigation> updateWrapper = AdminBuildUpdateWrapper(navigationQueryDTO, originalNavigation);
        boolean updated = navigationMapper.update(null, updateWrapper) > 0;
        if (!updated) {
            throw new RuntimeException("导航信息更新失败");
        }
    }

    private LambdaUpdateWrapper<Navigation> AdminBuildUpdateWrapper(NavigationQueryDTO navigationQueryDTO, Navigation originalNavigation) {
        LambdaUpdateWrapper<Navigation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Navigation::getId, navigationQueryDTO.getId())
                .set(Navigation::getUserId, originalNavigation.getUserId())
                .set(Navigation::getCategoryId, navigationQueryDTO.getCategory_id())
                .set(Navigation::getNavigationName, navigationQueryDTO.getNavigation_name())
                .set(Navigation::getNavigationLogo, navigationQueryDTO.getNavigation_logo())
                .set(Navigation::getNavigationUrl, navigationQueryDTO.getNavigation_url())
                .set(Navigation::getNavigationText, navigationQueryDTO.getNavigation_text())
                .set(Navigation::getSortOrder, originalNavigation.getSortOrder())
                .set(Navigation::getUpdateTime, new Date());
        return updateWrapper;
    }

    @Override
    public void AdminUpdateNavigationState(NavigationQueryDTO navigationQueryDTO) {
        // 空值检查
        Objects.requireNonNull(navigationQueryDTO, "CategoryDTO 不能为空");
        Objects.requireNonNull(navigationQueryDTO.getId(), "ID 不能为空");
        Objects.requireNonNull(navigationQueryDTO.getReason(), "Reason 不能为空");


        // 查询当前分类的状态
        QueryWrapper<Navigation> queryWrapper = new QueryWrapper<Navigation>().eq("id", navigationQueryDTO.getId());
        Navigation navigation = navigationMapper.selectOne(queryWrapper);

        if (navigation == null) {
            throw new RuntimeException("导航不存在");
        }


        if (!(Set.of("已驳回", "待审核", "无", "已发布").contains(navigation.getState()))) {
            throw new RuntimeException("未知的分类状态");
        }
        // 更新分类状态
        navigation.setState(navigationQueryDTO.getState());
        navigation.setUpdateTime(LocalDateTime.now());
        navigation.setReason(navigationQueryDTO.getReason());
        this.updateById(navigation);
    }

    @Override
    public void AdminDeleteByNavigationId(Integer id) {
        if (id == null) {
            throw new RuntimeException("ID不能为空");
        }

        this.removeById(id);
    }

    private String determineNewState(String currentState) {
        return switch (currentState) {
            case "无" -> "待审核";
            case "待审核", "已发布" -> "无";
            case "已驳回" -> "待审核";
            default -> null;
        };
    }
}